#!/bin/bash

# shellcheck source=meta-facebook/recipes-fb/obmc_functions/files/fb-common-functions
source /usr/libexec/fb-common-functions

phosphor_log() {
    busctl call \
        xyz.openbmc_project.Logging \
        /xyz/openbmc_project/logging \
        xyz.openbmc_project.Logging.Create \
        Create "ssa{ss}" "$1" "$2" 0
}

phosphor_log_err() {
    local msg=$1
    local logErr="xyz.openbmc_project.Logging.Entry.Level.Error"
    phosphor_log "$msg" "$logErr"
}

phosphor_log_info() {
    local msg=$1
    local logInfo="xyz.openbmc_project.Logging.Entry.Level.Informational"
    phosphor_log "$msg" "$logInfo"
}

get_pdb_cpld_ver()
{
    local pdb_cpld_ver=""

    pdb_cpld_ver="$(busctl get-property xyz.openbmc_project.Settings /xyz/openbmc_project/software/chassis/Catalina_PDB_cpld xyz.openbmc_project.Software.Version Version | awk '{print $2}' | tr -d '"')"
    if [ "$pdb_cpld_ver" != "" ]; then
        # Use the version record on settings service if avilable
        echo "$pdb_cpld_ver"
        return 0
    fi

    # Try i2ctransfer to get cpld version, echo empty string if failed
    if ! pdb_cpld_ver="$(i2ctransfer -y -f 14 w4@0x40 0xc0 0x00 0x00 0x00 r4)"; then
        echo ""
        return 1
    fi

    echo "$pdb_cpld_ver" | awk '{printf "%02x%02x%02x%02x\n", $1, $2, $3, $4}'
    return 0
}

is_rmc_main_power_disable()
{
    local pdb_cpld_ver=""
    local reg_val=""

    if ! pdb_cpld_ver="$(get_pdb_cpld_ver)"; then
        # unable to get pdb cpld version
        # assume rmc main power is enabled
        echo "[DEBUG] unable to get pdb cpld version"
        return 1
    fi

    if (( $((16#$pdb_cpld_ver)) < 0x10000 )); then
        # unable to check rmc main power state with pdb cpld version less than 0x10000
        # assume rmc main power is enabled
        echo "[DEBUG] pdb cpld version less than 0x10000"
        return 1
    fi

    if ! reg_val="$(i2ctransfer -y -f 14 w1@0x1e 0x0d r1)"; then
        # failed to get rmc main power state from cpld register
        # assume rmc main power is enabled
        echo "[DEBUG] failed to get rmc main power state from cpld register"
        return 1
    fi

    # check bit[3]
    # 1: rmc main power disabled
    # 0: rmc main power enabled
    if (( (reg_val & 0x08) == 0 )); then
        echo "[DEBUG] rmc main power is enabled"
        return 1
    fi

    echo "[DEBUG] rmc main power is disabled"
    return 0
}

chassis_power_cycle_ltc4287()
{
    if ! i2cset -f -y 20 0x42 0xfd 0x04; then
        echo "48V HSC1 set reboot delay failed"
        return 1
    fi

    if ! i2cset -f -y 20 0x43 0xfd 0x04; then
        echo "48V HSC2 set reboot delay failed"
        return 1
    fi

    if ! i2cset -f -y 20 0x42 0xfd 0x0c; then
        echo "48V HSC1 set reboot bit failed"
        return 1
    fi

    if ! i2cset -f -y 20 0x43 0xfd 0x0c; then
        echo "48V HSC2 set reboot bit failed"
        return 1
    fi

    return 0
}

chassis_power_cycle()
{
    chassis_power_cycle_ltc4287
    return $?
}

chassis_power_on()
{
    # MB stabdby power should enabled by before BMC ready
    # So only do checking here.
    if [ "$(chassis_power_status)" != "on" ]; then
        return 1
    fi
    return 0
}

chassis_power_status()
{
    if [ "$(get_gpio "STBY_POWER_PG_3V3")" -eq 1 ]; then
        echo "on"
    else
        echo "off"
    fi
}

host_power_on()
{
    if is_rmc_main_power_disable; then
        # Sleep for 10 seconds to avoid rapid consecutive retries
        sleep 10
        return 2
    fi

    if [ "$(host_power_status)" == "off" ]; then
        press_host_power_button 1
        if ! wait_host_power_on; then
            return 1
        fi
    fi
    return 0
}

host_force_power_off()
{
    if [ "$(host_power_status)" == "on" ]; then
        press_host_power_button 6
        if ! wait_host_power_off; then
            return 1
        fi
    fi
    return 0
}

host_graceful_power_off()
{
    if [ "$(host_power_status)" == "on" ]; then
        press_host_power_button 1
        if ! wait_host_power_off; then
            return 1
        fi
    fi
    return 0
}

host_power_status()
{
    if [ "$(get_gpio "host0-ready")" -eq 1 ]; then
        echo "on"
    else
        echo "off"
    fi
}

press_host_power_button()
{
    local press_delay_sec="$1"
    set_gpio "SYS_BMC_PWRBTN_R_N" 1
    set_gpio "SYS_BMC_PWRBTN_R_N" 0
    sleep "$press_delay_sec"
    set_gpio "SYS_BMC_PWRBTN_R_N" 1
}

wait_host_power_change()
{
    local exp_val="$1"
    local count=0
    until [ $count -gt 10 ]
    do
        sleep 1
        if [ "$(host_power_status)" == "$exp_val" ]; then
            return 0
        fi
        ((count++))
    done

    return 1
}

wait_host_power_on()
{
    wait_host_power_change "on"
    return $?
}

wait_host_power_off()
{
    wait_host_power_change "off"
    return $?
}